package org.colafries.admin.service.impl.index;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.colafries.admin.entity.domain.index.LogicCondition;
import org.colafries.admin.entity.vo.index.LogicConditionReqVO;
import org.colafries.admin.exceptions.ServiceException;
import org.colafries.admin.mapper.index.LogicConditionMapper;
import org.colafries.admin.service.impl.IBaseServiceImpl;
import org.colafries.admin.service.index.ILogicConditionService;
import org.colafries.common.constants.Constants;
import org.colafries.common.snowflake.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 业务限定表 服务实现类
 * </p>
 *
 * @author Ann
 * @since 2024-06-03
 */
@Service("LogicConditionServiceImpl")
@Slf4j
public class ILogicConditionServiceImpl extends IBaseServiceImpl<LogicConditionMapper, LogicCondition, LogicConditionReqVO> implements ILogicConditionService {

    @Autowired
    LogicConditionMapper logicConditionMapper;

    @Override
    public List<LogicCondition> listAll(LogicConditionReqVO vo) {
        return super.listAll(vo);
    }

    @Override
    public int add(LogicConditionReqVO vo) {
        // validate
        validateConditionReqVO(vo);
        //判断是否有同名
        LambdaQueryWrapper<LogicCondition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LogicCondition::getAlias, vo.getAlias());
        int conditionCnt = baseMapper.selectCount(queryWrapper);
        if (conditionCnt > 0) {
            log.warn("存在同名业务限定");
            throw new ServiceException("存在同名业务限定");
        }
        //新增业务限定
        Long code = SnowFlake.nextId();
        LogicCondition logicCondition = LogicCondition.builder()
                .code(code)
                .version(Constants.VERSION_FIRST)
                .logicTableCode(vo.getLogicTableCode())
                .field(vo.getField())
                .alias(vo.getAlias())
                .description(vo.getDescription())
                .expression(vo.getExpression())
                .createUser(vo.getCreateUser())
                .updateUser(vo.getUpdateUser())
                .build();
        return baseMapper.insert(logicCondition);
    }


    @Override
    public int update(LogicConditionReqVO vo) {
        // validate
        validateConditionReqVO(vo);
        Long logicCondCode = vo.getCode();
        LogicCondition oldCondition = this.queryByCode(logicCondCode);
        if (oldCondition == null) {
            log.warn("业务限定不存在 code:" + logicCondCode);
            throw new ServiceException("业务限定不存在 code:" + logicCondCode);
        }
        LogicCondition newCondition = LogicCondition.builder()
                .id(oldCondition.getId())
                .code(logicCondCode)
                .version(oldCondition.getVersion() + 1)
                .logicTableCode(vo.getLogicTableCode())
                .field(vo.getField())
                .alias(vo.getAlias())
                .description(vo.getDescription())
                .expression(vo.getExpression())
                .updateUser(vo.getUpdateUser())
                .build();
        return baseMapper.updateById(newCondition);
    }

    @Override
    public int delete(LogicConditionReqVO vo) {
        Long logicCondCode = vo.getCode();
        LogicCondition condition = this.queryByCode(logicCondCode);
        if (condition == null) {
            log.warn("业务限定不存在 code:" + logicCondCode);
            throw new ServiceException("业务限定不存在 code:" + logicCondCode);
        }
        //TODO 验证业务限定是否可以被删除
        this.conditionCanDeleteValid();
        return baseMapper.deleteById(condition.getId());
    }

    /**
     * 验证业务限定是否可以被删除
     * @return void
     * @Author anning
     * @Date 2024/6/11
     */
    private void conditionCanDeleteValid() {
        
    }

    @Override
    public IPage<LogicCondition> pageList(LogicConditionReqVO vo) {
        LambdaQueryWrapper<LogicCondition> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 其他筛选条件 ... ...
        Page<LogicCondition> page = new Page<>(vo.getCurrent(), vo.getSize());
        IPage<LogicCondition> result = logicConditionMapper.selectPage(page, queryWrapper);

        if (result.getTotal() > 0 && result.getRecords().isEmpty()) {
            long current = result.getPages();
            page = new Page<>((int) current, vo.getSize());
            result = logicConditionMapper.selectPage(page, queryWrapper);
        }
        return result;
    }

    /**
     * 业务限定Vo检查
     *
     * @param vo
     * @return void
     * @Author anning
     * @Date 2024/6/11
     */
    private void validateConditionReqVO(LogicConditionReqVO vo) {
        // 逻辑表code非空检查
        if (vo.getLogicTableCode() == null || vo.getLogicTableCode() == 0L) {
            log.warn("逻辑表code值非法");
            throw new ServiceException("逻辑表code值非法 code:" + vo.getLogicTableCode());
        }
        // 业务限定英文名检查
        if (StringUtils.isEmpty(vo.getField())) {
            log.warn("业务限定英文名不能为空");
            throw new ServiceException("业务限定英文名不能为空");
        }
        if (StringUtils.length(vo.getField()) > 50) {
            log.warn("业务限定英文名长度不能超过50");
            throw new ServiceException("业务限定英文名长度不能超过50");
        }
        // 业务限定英文名检查
        if (StringUtils.isEmpty(vo.getAlias())) {
            log.warn("业务限定名称不能为空");
            throw new ServiceException("业务限定名称不能为空");
        }
        if (StringUtils.length(vo.getAlias()) > 100) {
            log.warn("业务限定名称长度不能超过100");
            throw new ServiceException("业务限定名称长度不能超过100");
        }
        // 业务限定描述检查
        if (StringUtils.isEmpty(vo.getAlias())) {
            log.warn("业务限定描述不能为空");
            throw new ServiceException("业务限定描述不能为空");
        }
        if (StringUtils.length(vo.getAlias()) > 255) {
            log.warn("业务限定描述长度不能超过255");
            throw new ServiceException("业务限定描述长度不能超过255");
        }
        // 业务限定计算逻辑检查
        if (StringUtils.isEmpty(vo.getAlias())) {
            log.warn("业务限定计算逻辑不能为空");
            throw new ServiceException("业务限定计算逻辑不能为空");
        }
        if (StringUtils.length(vo.getAlias()) > 255) {
            log.warn("业务限定计算逻辑长度不能超过255");
            throw new ServiceException("业务限定计算逻辑长度不能超过255");
        }
    }

    /**
     * 根据code查询业务限定
     * @param logicCondCode
     * @return org.colafries.admin.entity.domain.index.LogicCondition
     * @Author anning
     * @Date 2024/6/11
     */
    @Override
    public LogicCondition queryByCode(Long logicCondCode){
        LambdaQueryWrapper<LogicCondition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LogicCondition::getCode, logicCondCode);
        return baseMapper.selectOne(queryWrapper);
    }
}
